home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / FlowLayout.java < prev    next >
Text File  |  1998-09-22  |  11KB  |  370 lines

  1. /*
  2.  * @(#)FlowLayout.java    1.27 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. /**
  17.  * A flow layout arranges components in a left-to-right flow, much 
  18.  * like lines of text in a paragraph. Flow layouts are typically used 
  19.  * to arrange buttons in a panel. It will arrange
  20.  * buttons left to right until no more buttons fit on the same line.
  21.  * Each line is centered.
  22.  * <p>
  23.  * For example, the following picture shows an applet using the flow 
  24.  * layout manager (its default layout manager) to position three buttons:
  25.  * <p>
  26.  * <img src="images-awt/FlowLayout-1.gif" 
  27.  * ALT="Graphic of Layout for Three Buttons" 
  28.  * ALIGN=center HSPACE=10 VSPACE=7>
  29.  * <p>
  30.  * Here is the code for this applet: 
  31.  * <p>
  32.  * <hr><blockquote><pre>
  33.  * import java.awt.*;
  34.  * import java.applet.Applet;
  35.  * 
  36.  * public class myButtons extends Applet {
  37.  *     Button button1, button2, button3;
  38.  *     public void init() {
  39.  *         button1 = new Button("Ok");
  40.  *         button2 = new Button("Open");
  41.  *         button3 = new Button("Close");
  42.  *         add(button1);
  43.  *         add(button2);
  44.  *         add(button3);
  45.  *     }
  46.  * }
  47.  * </pre></blockquote><hr>
  48.  * <p>
  49.  * A flow layout lets each component assume its natural (preferred) size. 
  50.  *
  51.  * @version     1.27, 07/01/98
  52.  * @author     Arthur van Hoff
  53.  * @author     Sami Shaio
  54.  * @since       JDK1.0
  55.  */
  56. public class FlowLayout implements LayoutManager, java.io.Serializable {
  57.  
  58.     /**
  59.      * This value indicates that each row of components
  60.      * should be left-justified. 
  61.      * @since   JDK1.0 
  62.      */
  63.     public static final int LEFT     = 0;
  64.  
  65.     /**
  66.      * This value indicates that each row of components
  67.      * should be centered. 
  68.      * @since   JDK1.0 
  69.      */
  70.     public static final int CENTER     = 1;
  71.  
  72.     /**
  73.      * This value indicates that each row of components
  74.      * should be right-justified. 
  75.      * @since   JDK1.0
  76.      */
  77.     public static final int RIGHT     = 2;
  78.  
  79.     int align;
  80.     int hgap;
  81.     int vgap;
  82.  
  83.     /*
  84.      * JDK 1.1 serialVersionUID 
  85.      */
  86.      private static final long serialVersionUID = -7262534875583282631L;
  87.  
  88.     /**
  89.      * Constructs a new Flow Layout with a centered alignment and a
  90.      * default 5-unit horizontal and vertical gap.
  91.      * @since JDK1.0
  92.      */
  93.     public FlowLayout() {
  94.     this(CENTER, 5, 5);
  95.     }
  96.  
  97.     /**
  98.      * Constructs a new Flow Layout with the specified alignment and a
  99.      * default 5-unit horizontal and vertical gap.
  100.      * The value of the alignment argument must be one of 
  101.      * <code>FlowLayout.LEFT</code>, <code>FlowLayout.RIGHT</code>, 
  102.      * or <code>FlowLayout.CENTER</code>.
  103.      * @param align the alignment value
  104.      * @since JDK1.0
  105.      */
  106.     public FlowLayout(int align) {
  107.     this(align, 5, 5);
  108.     }
  109.  
  110.     /**
  111.      * Creates a new flow layout manager with the indicated alignment 
  112.      * and the indicated horizontal and vertical gaps. 
  113.      * <p>
  114.      * The value of the alignment argument must be one of 
  115.      * <code>FlowLayout.LEFT</code>, <code>FlowLayout.RIGHT</code>, 
  116.      * or <code>FlowLayout.CENTER</code>.  
  117.      * @param      align   the alignment value.
  118.      * @param      hgap    the horizontal gap between components.
  119.      * @param      vgap    the vertical gap between components.
  120.      * @since      JDK1.0
  121.      */
  122.     public FlowLayout(int align, int hgap, int vgap) {
  123.     this.align = align;
  124.     this.hgap = hgap;
  125.     this.vgap = vgap;
  126.     }
  127.  
  128.     /**
  129.      * Gets the alignment for this layout.
  130.      * Possible values are <code>FlowLayout.LEFT</code>,  
  131.      * <code>FlowLayout.RIGHT</code>, or <code>FlowLayout.CENTER</code>.  
  132.      * @return     the alignment value for this layout.
  133.      * @see        java.awt.FlowLayout#setAlignment
  134.      * @since      JDK1.1
  135.      */
  136.     public int getAlignment() {
  137.     return align;
  138.     }
  139.     
  140.     /**
  141.      * Sets the alignment for this layout.
  142.      * Possible values are <code>FlowLayout.LEFT</code>,  
  143.      * <code>FlowLayout.RIGHT</code>, and <code>FlowLayout.CENTER</code>.  
  144.      * @param      align the alignment value.
  145.      * @see        java.awt.FlowLayout#getAlignment
  146.      * @since      JDK1.1
  147.      */
  148.     public void setAlignment(int align) {
  149.     this.align = align;
  150.     }
  151.  
  152.     /**
  153.      * Gets the horizontal gap between components.
  154.      * @return     the horizontal gap between components.
  155.      * @see        java.awt.FlowLayout#setHgap
  156.      * @since      JDK1.1
  157.      */
  158.     public int getHgap() {
  159.     return hgap;
  160.     }
  161.     
  162.     /**
  163.      * Sets the horizontal gap between components.
  164.      * @param hgap the horizontal gap between components
  165.      * @see        java.awt.FlowLayout#getHgap
  166.      * @since      JDK1.1
  167.      */
  168.     public void setHgap(int hgap) {
  169.     this.hgap = hgap;
  170.     }
  171.     
  172.     /**
  173.      * Gets the vertical gap between components.
  174.      * @return     the vertical gap between components.
  175.      * @see        java.awt.FlowLayout#setVgap
  176.      * @since      JDK1.1
  177.      */
  178.     public int getVgap() {
  179.     return vgap;
  180.     }
  181.     
  182.     /**
  183.      * Sets the vertical gap between components.
  184.      * @param vgap the vertical gap between components
  185.      * @see        java.awt.FlowLayout#getVgap
  186.      * @since      JDK1.1
  187.      */
  188.     public void setVgap(int vgap) {
  189.     this.vgap = vgap;
  190.     }
  191.  
  192.     /**
  193.      * Adds the specified component to the layout. Not used by this class.
  194.      * @param name the name of the component
  195.      * @param comp the component to be added
  196.      * @since JDK1.0
  197.      */
  198.     public void addLayoutComponent(String name, Component comp) {
  199.     }
  200.  
  201.     /**
  202.      * Removes the specified component from the layout. Not used by
  203.      * this class.  
  204.      * @param comp the component to remove
  205.      * @see       java.awt.Container#removeAll
  206.      * @since     JDK1.0
  207.      */
  208.     public void removeLayoutComponent(Component comp) {
  209.     }
  210.  
  211.     /**
  212.      * Returns the preferred dimensions for this layout given the components
  213.      * in the specified target container.
  214.      * @param target the component which needs to be laid out
  215.      * @return    the preferred dimensions to lay out the 
  216.      *                    subcomponents of the specified container.
  217.      * @see Container
  218.      * @see #minimumLayoutSize
  219.      * @see       java.awt.Container#getPreferredSize
  220.      * @since     JDK1.0
  221.      */
  222.     public Dimension preferredLayoutSize(Container target) {
  223.       synchronized (target.getTreeLock()) {
  224.     Dimension dim = new Dimension(0, 0);
  225.     int nmembers = target.getComponentCount();
  226.  
  227.     for (int i = 0 ; i < nmembers ; i++) {
  228.         Component m = target.getComponent(i);
  229.         if (m.visible) {
  230.         Dimension d = m.getPreferredSize();
  231.         dim.height = Math.max(dim.height, d.height);
  232.         if (i > 0) {
  233.             dim.width += hgap;
  234.         }
  235.         dim.width += d.width;
  236.         }
  237.     }
  238.     Insets insets = target.getInsets();
  239.     dim.width += insets.left + insets.right + hgap*2;
  240.     dim.height += insets.top + insets.bottom + vgap*2;
  241.     return dim;
  242.       }
  243.     }
  244.  
  245.     /**
  246.      * Returns the minimum dimensions needed to layout the components
  247.      * contained in the specified target container.
  248.      * @param target the component which needs to be laid out 
  249.      * @return    the minimum dimensions to lay out the 
  250.      *                    subcomponents of the specified container.
  251.      * @see #preferredLayoutSize
  252.      * @see       java.awt.Container
  253.      * @see       java.awt.Container#doLayout
  254.      * @since     JDK1.0
  255.      */
  256.     public Dimension minimumLayoutSize(Container target) {
  257.       synchronized (target.getTreeLock()) {
  258.     Dimension dim = new Dimension(0, 0);
  259.     int nmembers = target.getComponentCount();
  260.  
  261.     for (int i = 0 ; i < nmembers ; i++) {
  262.         Component m = target.getComponent(i);
  263.         if (m.visible) {
  264.         Dimension d = m.getMinimumSize();
  265.         dim.height = Math.max(dim.height, d.height);
  266.         if (i > 0) {
  267.             dim.width += hgap;
  268.         }
  269.         dim.width += d.width;
  270.         }
  271.     }
  272.     Insets insets = target.getInsets();
  273.     dim.width += insets.left + insets.right + hgap*2;
  274.     dim.height += insets.top + insets.bottom + vgap*2;
  275.     return dim;
  276.       }
  277.     }
  278.  
  279.     /** 
  280.      * Centers the elements in the specified row, if there is any slack.
  281.      * @param target the component which needs to be moved
  282.      * @param x the x coordinate
  283.      * @param y the y coordinate
  284.      * @param width the width dimensions
  285.      * @param height the height dimensions
  286.      * @param rowStart the beginning of the row
  287.      * @param rowEnd the the ending of the row
  288.      */
  289.     private void moveComponents(Container target, int x, int y, int width, int height, int rowStart, int rowEnd) {
  290.       synchronized (target.getTreeLock()) {
  291.     switch (align) {
  292.     case LEFT:
  293.         break;
  294.     case CENTER:
  295.         x += width / 2;
  296.         break;
  297.     case RIGHT:
  298.         x += width;
  299.         break;
  300.     }
  301.     for (int i = rowStart ; i < rowEnd ; i++) {
  302.         Component m = target.getComponent(i);
  303.         if (m.visible) {
  304.         m.setLocation(x, y + (height - m.height) / 2);
  305.         x += hgap + m.width;
  306.         }
  307.     }
  308.       }
  309.     }
  310.  
  311.     /**
  312.      * Lays out the container. This method lets each component take 
  313.      * its preferred size by reshaping the components in the 
  314.      * target container in order to satisfy the constraints of
  315.      * this <code>FlowLayout</code> object. 
  316.      * @param target the specified component being laid out.
  317.      * @see Container
  318.      * @see       java.awt.Container#doLayout
  319.      * @since     JDK1.0
  320.      */
  321.     public void layoutContainer(Container target) {
  322.       synchronized (target.getTreeLock()) {
  323.     Insets insets = target.getInsets();
  324.     int maxwidth = target.width - (insets.left + insets.right + hgap*2);
  325.     int nmembers = target.getComponentCount();
  326.     int x = 0, y = insets.top + vgap;
  327.     int rowh = 0, start = 0;
  328.  
  329.     for (int i = 0 ; i < nmembers ; i++) {
  330.         Component m = target.getComponent(i);
  331.         if (m.visible) {
  332.         Dimension d = m.getPreferredSize();
  333.         m.setSize(d.width, d.height);
  334.     
  335.         if ((x == 0) || ((x + d.width) <= maxwidth)) {
  336.             if (x > 0) {
  337.             x += hgap;
  338.             }
  339.             x += d.width;
  340.             rowh = Math.max(rowh, d.height);
  341.         } else {
  342.             moveComponents(target, insets.left + hgap, y, maxwidth - x, rowh, start, i);
  343.             x = d.width;
  344.             y += vgap + rowh;
  345.             rowh = d.height;
  346.             start = i;
  347.         }
  348.         }
  349.     }
  350.     moveComponents(target, insets.left + hgap, y, maxwidth - x, rowh, start, nmembers);
  351.       }
  352.     }
  353.     
  354.     /**
  355.      * Returns a string representation of this <code>FlowLayout</code>
  356.      * object and its values.
  357.      * @return     a string representation of this layout.
  358.      * @since      JDK1.0
  359.      */
  360.     public String toString() {
  361.     String str = "";
  362.     switch (align) {
  363.       case LEFT:    str = ",align=left"; break;
  364.       case CENTER:  str = ",align=center"; break;
  365.       case RIGHT:   str = ",align=right"; break;
  366.     }
  367.     return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + str + "]";
  368.     }
  369. }
  370.